package cn.tianwt.proxy;

import cn.tianwt.proxy.http.utils.Configs;
import cn.tianwt.proxy.http.utils.LogUtils;

public class ServerThread  extends Thread{

	private Context context;
	private long timeout;
	private int retryCount;
	private int port;
	

	@Override
	public void run() {
		super.run();
			try {
				this.startApplication();
			} catch (Exception e) {
				e.printStackTrace();
				try {
					this.stopApplication();
				} catch (Exception ignore) {
					ignore.printStackTrace();
				}
			}
		
	}
	
	
	private void startApplication() throws Exception {
		try {
			this.checkAccess();
			
			this.context.setPort(port);
			this.context.setTimeout(this.timeout);
			
			boolean isReady = this.context.isReady();
			int counter = 0;
			while(!isReady) {
				this.context.onCreated();
				isReady = this.context.isReady();
				if(counter>retryCount) {
					break;
				}
				
				counter++;
			}
			if(!isReady) {
				this.context.onDestory();
				LogUtils.E( "Application can't be created");
				throw new IllegalArgumentException( "Application can't be created");
			}
			this.context.onStart();
		}catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		
	}

	
	public void stopApplication() throws Exception {
		if(this.context==null) return;
		boolean isPaused = this.context.isPaused();
		int counter = 0;
		while(isPaused) {
			this.context.onPause();
			if(counter>retryCount) {
				break;
			}
			this.context.isPaused();
			counter++;
		}
		if(isPaused) {
			LogUtils.E( "Application can't be closed");
			System.gc();
			System.exit(-1);
			return;
		}
		this.context.onDestory();
	}
	
	public void setPort(int port) {
		this.port = port;
	}
	
	public void setRetryCount(int retryCount) {
		this.retryCount = retryCount;
	}
	
	
	public void setContext(Context context) {
		this.context = context;
	}


	public void setTimeout(long timeout) {
		this.timeout = timeout;
	}


	public static class Builder{
		
		private Context context;
		private long timeout;
		private boolean isDeamon;
		private int priority;
		private int retryCount;
		private int port = 1080;
		
		public Builder attach(Context context) {
			this.context = context;
			return this;
		}
		
		public Builder soTimeout(long timeout) {
			this.timeout = timeout;
			return this;
		}
		
		public Builder isDeamon(boolean isDeamon) {
			this.isDeamon = isDeamon;
			return this;
		}
		
		public Builder priority(int priority){
			this.priority = priority;
			return this;
		}
		public Builder retryCount(int retryCount){
			this.retryCount = retryCount;
			return this;
		}
		public Builder port(int port){
			this.port = port;
			return this;
		}

		public ServerThread build() {
			ServerThread serverThread = new ServerThread();
			serverThread.setContext(context);
			serverThread.setTimeout(timeout);
			serverThread.setDaemon(isDeamon);
			serverThread.setPriority(priority);
			serverThread.setRetryCount(retryCount);
			serverThread.setPort(port);
			serverThread.setName(Configs.SERVER_THREAD_NAME);
			return serverThread;
		}
	}


	public  boolean  isShutDown() {
		return this.context==null || !this.context.isRunning();
	}


}
